<template>
  <div
    :class="`map-regions-tree ${componentStyle_}-Style`"
    @click.stop
  >
    <span
      class="regions-tree-current-name"
      :title="currentRegionName()"
      @click.stop="regionTreeShow = !regionTreeShow"
    >
      {{ currentRegionName() }}
      <el-icon :class="{ 'el-icon-arrow-down': true, closeTree: regionTreeShow }"><ArrowDown /></el-icon>
    </span>
    <div
      v-show="regionTreeShow"
      class="regions-tree-body"
    >
      <el-input
        v-model="filterText"
        size="large"
        class="regions-tree-search"
        :placeholder="$demoi18n('placeholder.plsEnterAreaName')"
        @keyup.enter="filterTreeFun"
      ></el-input>
      <el-icon class="regions-search-icon" @click="filterTreeFun"><Search /></el-icon>
      <el-scrollbar class="filter-tree-scroll">
        <div class="filter-tree-scroll-box">
          <el-tree
            v-show="!filterTreeShow"
            ref="tree"
            class="filter-tree"
            node-key="code"
            accordion
            highlight-current
            check-on-click-node
            :data="treeList"
            :default-expanded-keys="defaultExpandedKeys"
            :props="defaultProps"
            :expand-on-click-node="false"
            :load="loadNode"
            lazy
            :filter-node-method="filterNode"
            @node-click="regionsClick"
          ></el-tree>
          <div
            v-show="filterTreeShow"
            class="filter-result"
          >
            <ul v-show="!isNoData">
              <li
                v-for="(item, index) in filterResultList"
                :key="index"
                @click="selectResult(item)"
              >
                <i class="result-bg"></i>
                <span>{{ item.fullName }}</span>
              </li>
            </ul>
            <span
              v-show="isNoData"
              class="isNoData"
            >
              {{ $demoi18n('word.noDataAvailable') }}
            </span>
          </div>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>
<script>
import regionApi from '@/apis/region.js';
import EventBus from '@/event-bus/EventBus.js';
import { mapActions, mapState } from 'vuex';
import { nextTick } from 'vue';
import { $message } from '@/utils/util.js';

export default {
  name: 'RegionsTree',

  props: ['closeTree', 'config', 'componentStyle'],
  emits: ['_resource_clearSearchLayer'],
  data() {
    return {
      filterText: '',
      treeList: [],
      defaultProps: {
        children: 'children',
        label: 'name',
        isLeaf: 'isLeaf',
      },
      regionTreeShow: false,
      defaultExpandedKeys: [], // 默认开启的节点key
      filterTreeShow: false, // 树状选择框
      filterResultList: [], // 过滤结果数组
      isNoData: false, // 无数据
      listener: null,
      codeMap: {},
      parentCodeMap: {},
      i18nConfig: {},
    };
  },
  computed: {
    ...mapState({
      regions: state => state.RegionModule.allRegions || [],
      currentRegionCode: state => state.RegionModule.currentRegionCode,
      loginRegionCode: state => state.RegionModule.loginRegionCode,
    }),
    componentStyle_() {
      return this.componentStyle || this.config.config.property.componentStyle;
    },
  },
  watch: {
    filterText(val) {
      if (val === '') {
        this.filterTreeShow = false;
      }
    },
    currentRegionCode(newVal, oldVal) {
      // 当前区域发生变化
      if (newVal !== oldVal) {
        // 设置面包屑
        this.regionTreeShow = false;
        this.getLackRegionData(newVal);
      }
    },
  },
  mounted() {
    this.init();

    // 点击外部收起
    this.listener = e => {
      if (!this.$el.contains(e.target)) {
        this.regionTreeShow = false;
        this.filterText = '';
      }
    };
    document.addEventListener('click', this.listener, true);
  },
  beforeUnmount() {
    document.removeEventListener('click', this.listener, true);
  },
  methods: {
    ...mapActions(['getAllRegions', 'setCurrentRegion']),
    currentRegionName() {
      if (this.codeMap[this.currentRegionCode]) {
        return this.codeMap[this.currentRegionCode].name;
      } else {
        return '';
      }
    },
    init() {
      // 处理区域数据
      const regions = JSON.parse(JSON.stringify(this.regions));
      const codeMap = {};
      const parentCodeMap = {};
      for (let i = 0; i < regions.length; i++) {
        regions[i]['parent_code'] = regions[i].parentCode;
        codeMap[regions[i].code] = regions[i];
        if (regions[i].parent_code) {
          if (!parentCodeMap[regions[i].parent_code]) {
            parentCodeMap[regions[i].parent_code] = [];
          }
          parentCodeMap[regions[i].parent_code].push(regions[i]);
        }
      }
      this.parentCodeMap = parentCodeMap;
      this.codeMap = codeMap;
      if (this.codeMap[this.currentRegionCode]) {
        this.openCurrentRegionNode();
      } else {
        this.getLackRegionData(this.currentRegionCode);
      }
    },

    // 初始化列表
    formatRegions() {
      if (this.loginRegionCode) {
        const { loginRegionCode } = this;
        let tree;
        const rootNode = JSON.parse(JSON.stringify(this.codeMap[loginRegionCode]));
        if (this.parentCodeMap[loginRegionCode] && this.parentCodeMap[loginRegionCode].length !== 0) {
          tree = this.filterArray([rootNode]);
        } else {
          tree = [rootNode];
        }
        this.treeList = tree;
      }
    },

    // 展开当前区域节点
    openCurrentRegionNode() {
      if (!this.treeList.length) {
        this.formatRegions();
      }
      if (this.currentRegionCode) {
        this.filterText = '';
        const currentRegionObj = this.codeMap[this.currentRegionCode];
        this.defaultExpandedKeys = currentRegionObj.pathCode.split(',');
        nextTick(() => {
          this.$refs.tree.setChecked(this.currentRegionCode);
          this.$refs.tree.setCurrentKey(this.currentRegionCode); // treeBox 元素的ref   value 绑定的node-key
        });
      }
    },

    // 递归处理数组
    filterArray(arr) {
      for (let i = 0; i < arr.length; i++) {
        if (this.parentCodeMap[arr[i].code] && this.parentCodeMap[arr[i].code].length !== 0) {
          arr[i].children = this.parentCodeMap[arr[i].code];
          this.filterArray(arr[i].children);
        }
      }
      return arr;
    },

    // 过滤数据
    filterNode(value, data) {
      if (!value) {
        return true;
      }
      return data.label.indexOf(value) !== -1;
    },

    // 处理区域点击事件
    regionsClick(data) {
      EventBus.$emit('_resource_clearSearchLayer');
      this.setCurrentRegion(data.code);
    },
    loadNode(node, resolve) {
      if (this.parentCodeMap[node.data.code]) {
        if (this.config.config && String(this.config.config.property.maxLevel - 1) === String(node.data.level)) {
          this.parentCodeMap[node.data.code].forEach(e => {
            e.isLeaf = true;
          });
        }
        resolve(this.parentCodeMap[node.data.code]);
      } else {
        if (!node.data.code) {
          return;
        }
        regionApi
          .getCurrentRegionPrtChdRegs(node.data.code)
          .then(res => {
            const regions = res;
            for (let i = 0; i < regions.length; i++) {
              regions[i]['parent_code'] = regions[i].parentCode;
              this.codeMap[regions[i].code] = regions[i];
              if (regions[i].parent_code) {
                if (!this.parentCodeMap[regions[i].parent_code]) {
                  this.parentCodeMap[regions[i].parent_code] = [];
                }
                if (String(node.data.level + 1) === String(regions[i].level)) {
                  this.parentCodeMap[regions[i].parent_code].push(regions[i]);
                }
              }
            }
            if (this.config.config && String(this.config.config.property.maxLevel) === String(node.data.level)) {
              this.parentCodeMap[node.data.code].forEach(e => {
                e.isLeaf = true;
              });
            }
            resolve(this.parentCodeMap[node.data.code] || []);
          })
          .catch(err => {
            resolve([]);
          });
      }
    },

    // 过滤结果到结果框
    filterTreeFun() {
      if (this.filterText) {
        this.filterResultList = [];
        regionApi.queryGridByName(this.filterText, this.loginRegionCode).then(res => {
          if (res.status === 403) {
            $message({
              type: 'warning',
              message: '当前用户角色缺少【xminer 数据查询】或【xminer 数据管理】权限，请到IAM进行授权',
            });
          }
          this.filterTreeShow = true;
          if (String(res.data.code) === '1') {
            const result = res.data.data;
            this.filterResultList = result;
            if (this.filterResultList.length === 0) {
              this.isNoData = true;
            } else {
              this.isNoData = false;
            }
          } else {
            this.isNoData = true;
          }
        });
      } else {
        this.filterTreeShow = false;
      }
    },

    // 处理查询出的区域点击事件
    selectResult(data) {
      EventBus.$emit('_resource_clearSearchLayer');
      this.setCurrentRegion(data.code);
    },
    getLackRegionData(regionCode) {
      if (this.parentCodeMap[regionCode]) {
        // 已有数据中存在该regionCode
        this.openCurrentRegionNode();
      } else {
        regionApi.getCurrentRegionPrtChdRegs(regionCode).then(res => {
          const regions = res;
          const regionObj = regions.find(r => String(r.code) === String(regionCode));

          for (let i = 0; i < regions.length; i++) {
            regions[i]['parent_code'] = regions[i].parentCode;
            if (regions[i].level <= regionObj.level) {
              continue;
            }
            this.codeMap[regions[i].code] = regions[i];
            if (regions[i].parent_code) {
              if (!this.parentCodeMap[regions[i].parent_code]) {
                this.parentCodeMap[regions[i].parent_code] = [];
              }
              this.parentCodeMap[regions[i].parent_code].push(regions[i]);
            }
          }
          this.getLackRegionData(regionObj.parent_code);
        });
      }
    },
  },
};
</script>
<style lang="less" scoped>
.map-regions-tree {
  display: inline-block;
  position: relative;
  box-sizing: border-box;
  height: 25px;

  .regions-tree-current-name {
    height: 25px;
    padding: 0 30px 0 15px;
    max-width: 300px;
    line-height: 25px;
    display: inline-block;
    cursor: pointer;
    position: relative;
    text-align: center;
    font-size: 14px;

    overflow: hidden; //超出的文本隐藏
    text-overflow: ellipsis; //溢出用省略号显示
    white-space: nowrap; //溢出不换行

    .el-icon-arrow-down {
      position: absolute;
      right: 5px;
      top: calc(50% - 8px);
      transition: all 0.2s linear;
    }

    .el-icon-arrow-down.closeTree {
      transform: rotate(-180deg);
    }
  }

  .regions-tree-body {
    position: absolute;
    left: 0;
    top: 100%;
    overflow: hidden;
    width: 300px;
    height: 480px;

    .regions-tree-search {
      padding: 10px;
      box-sizing: border-box;
      font-size: 12px;
    }

    .regions-search-icon {
      position: absolute;
      right: 20px;
      top: 23px;
      z-index: 2;
    }

    .filter-tree-scroll {
      height: calc(100% - 51px);

      &::before {
        content: ' ';
        display: block;
        width: 100%;
        height: 10px;
        position: absolute;
        bottom: 0;
        left: 0;
        z-index: 2;
      }

      .filter-tree-scroll-box {
        padding: 10px 10px 0 10px;
      }

      .filter-result {
        .isNoData {
          display: inline-block;
          width: 100%;
          height: auto;
          text-align: center;
          font-size: 14px;
        }

        ul {
          margin: 0;
          padding: 0 10px 10px 0;
          user-select: none;
          text-align: left;

          li {
            list-style: none;
            margin: 0;
            padding: 2px 0;
            cursor: pointer;
            white-space: nowrap;
            word-break: keep-all;
            transition: color 0.2s;
            font-size: 12px;
            height: 20px;
            line-height: 20px;
            position: relative;

            span {
              position: relative;
              z-index: 1;
              display: inline-block;
              padding: 0 10px;
            }

            .result-bg {
              display: none;
              height: 100%;
              width: 160%;
              position: absolute;
              top: 0;
              left: 0;
              z-index: 0;
            }

            &:hover {
              .result-bg {
                display: block;
              }
            }
          }
        }
      }
    }
  }
}
</style>
<style lang="less" scoped>
@import './style/theme.less';
.map-regions-tree {
  border: 1px solid var(--border-color);
  color: var(--color);
  background-color: var(--vs-bg-color);
  height: 27px;

  .regions-tree-current-name{
    color: var(--tree-current-name-color);
    background-color: var(--bg-color);
  }

  // 树选择复用函数
  .tree-select-style {
    background-color: var(--tree-select-style-bg-color);
    color: var(--tree-select-style-color);
  }

  .no-tree-select-style {
    background-color: transparent;
    color: var(--tree-select-style-color);
  }

  .filter-tree-scroll-box{
    background-color: var(--bg-color);
  }

  .regions-tree-body {
    border: 1px solid var(--border-color);
    background-color: var(--bg-color);
    box-shadow: 0px 0px 1px var(--regions-tree-body-shadow-color);

    .regions-tree-search {
      background-color: var(--bg-color);
      border-bottom: 1px solid var(--regions-tree-search-border-color);
    }

    .regions-search-icon {
      color: var(--regions-search-icon-color);
    }

    .filter-tree-scroll {
      &::before {
        background-color: var(--bg-color);
      }
    }

    .filter-result {
      .isNoData {
        color: var(--isNoData-color);
      }
    }

    ul {
      li {
        color: var(--primary-color);

        .result-bg {
          background-color: var(--bg-color);
        }
      }
    }
  }

  :deep(.el-tree-node__content) {
    padding-left: 23px;
  }
}
</style>

<style lang="less">
// // 亮的风格
// @import './style/theme-default.less';
// // 深色风格
// @import './style/theme-dark.less';
.map-regions-tree {
  .filter-tree {
    .regions-tree-body .regions-tree-search .el-input__wrapper {
      height: 30px;
      line-height: 30px;
      padding-right: 30px;
    }

    .el-scrollbar__wrap {
      overflow-x: hidden;

      .el-tree > .el-tree-node {
        display: inline-block;
        width: 100%;

        .el-tree-node__expand-icon:not(.is-leaf)::before {
          content: ' ';
          background-image: url('./images/regions-tree-icon.png');
          background-position: center center;
          background-repeat: no-repeat;
          width: 12px;
          height: 12px;
          display: inline-block;
        }
      }
    }

    .el-scrollbar__bar {
      z-index: 3;
    }
  }
}
</style>
